package gp.app;

import genetic.Population;
import genetic.treeelements.Function;
import genetic.treeelements.InputVariable;
import genetic.treeelements.Terminal;
import genetic.treeelements.functions.Addition;
import genetic.treeelements.functions.Division;
import genetic.treeelements.functions.Multiplication;
import genetic.treeelements.functions.Subtraction;

import java.util.ArrayList;
import java.util.Random;

import jfchelper.XYSeriesFactory;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class Basic extends ApplicationFrame {

	private Population pop;
    XYSeriesCollection visualizationData = new XYSeriesCollection();

    public Basic(String title) {

        super(title);

        pop = new Population();

        // setup function set
        ArrayList<Function> functionSet = new ArrayList<Function>();
        functionSet.add(new Addition());
        functionSet.add(new Subtraction());
        functionSet.add(new Multiplication());
        functionSet.add(new Division());

        // setup input-set and desired target-set
        ArrayList<InputVariable> inputSet = new ArrayList<InputVariable>();
        InputVariable x1 = new InputVariable("x1");
        x1.setData(XYSeriesFactory.loadFromExcel("testdata.xls", "x1", 1));
        inputSet.add(x1);

        // setup terminal-set
        ArrayList<Terminal> terminalSet = new ArrayList<Terminal>();
        Random rd = new Random();
        for (int i=0; i<2; i++) {
            terminalSet.add(new Terminal(rd.nextDouble()*5));
        }

        XYSeries y1 = XYSeriesFactory.loadFromExcel("testdata.xls", "y1", 1);
        XYSeriesCollection targetData = new XYSeriesCollection();
        targetData.addSeries(y1);

        visualizationData.addSeries(y1);
        
        pop.setInputSet(inputSet);
        pop.setTerminalSet(terminalSet);
        pop.setTargetData(targetData);
        pop.setFunctionSet(functionSet);
        pop.setMaxGenerations(100);
        pop.setView(this);

        pop.createRandom(100, 6);

        JFreeChart chart = createChart(visualizationData);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
        setContentPane(chartPanel);

        pop.start();
        
    }
    
    private static JFreeChart createChart(XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart(
            "",
            "", 
            "", 
            dataset,
            PlotOrientation.VERTICAL,
            false,
            false,
            false
        );
        return chart;
    }

    public void change() {
    	visualizationData.addSeries(pop.calcBest());
    	if (visualizationData.getSeriesCount() >= 3)
    		visualizationData.removeSeries(1);
    }
    
    public static void main(String[] args) {

        Basic demo = new Basic("Basic");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}
